package com.egoonet.dao;

import com.egoonet.domain.Department;
import com.egoonet.dept.DepartmentTree;
import com.egoonet.dept.Node;
import com.egoonet.domain.Employee;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 *
 * Created by wchi on 2017/4/22.
 */
@Service
public class DepartmentTreeDao {
    @Autowired
    DepartmentRepository departmentRepository;

    @Autowired
    EmployeeRepository employeeRepository;

    public void saveOrUpdate(DepartmentTree DepartmentTree) {
        List<Node<Department>> Departments = DepartmentTree.toList();
        // save the tree in reverse order, starting from the leaf nodes
        // and going up to the root of the tree.
        int numberOfNodes = Departments.size();
        for (int i = numberOfNodes - 1; i >= 0; i--) {
            Node<Department> DepartmentElement = Departments.get(i);
            Department Department = DepartmentElement.getData();
            departmentRepository.save(Department);
            Long parentId = Department.getId();
            for (Iterator<Node<Department>> it = DepartmentElement.getChildren().iterator(); it.hasNext();) {
                Node<Department> childElement = it.next();
                Department childDepartment = childElement.getData();
                childDepartment.setParentId(parentId);
                departmentRepository.save(childDepartment);
            }
        }
    }

    /**
     * Gets a single DepartmentTree by id. This is the head of a recursive method call
     * to getRecursive().
     * @param id the id of the DepartmentTree.
     * @param isAppendEmployees 是否为部门增加员工数据
     * @return a DepartmentTree for that id.
     */
    public DepartmentTree get(Long id, boolean isAppendEmployees) {
        DepartmentTree DepartmentTree = new DepartmentTree();
        Department department = departmentRepository.findOne(id);
        Node<Department> rootElement = new Node<>(department);
        getRecursive(rootElement, DepartmentTree, isAppendEmployees);
        DepartmentTree.setRootElement(rootElement);
        return DepartmentTree;
    }

    /**
     * Recursively descends the Tree and populates the DepartmentTree object.
     * @param DepartmentElement the root Node.
     * @param isAppendEmployees 是否为部门增加员工数据
     * @param tree the DepartmentTree object to populate.
     */
    private void getRecursive(Node<Department> DepartmentElement, DepartmentTree tree, boolean isAppendEmployees) {
        Department pdept = DepartmentElement.getData();
        //为部门附加员工数据
        if(isAppendEmployees){
            List<Employee> employees = employeeRepository.findByDepartment(pdept);
            if(employees!=null && employees.size()>0){
                pdept.setEmployees(employees);
            }
        }

        List<Department> children = departmentRepository.findByParentId(pdept.getId());
        List<Node<Department>> childElements = new ArrayList<>();
        for (Iterator<Department> it = children.iterator(); it.hasNext();) {
            Department childDepartment = it.next();
            Node<Department> childElement = new Node<>(childDepartment);
            childElements.add(childElement);
            getRecursive(childElement, tree, isAppendEmployees);
        }
        DepartmentElement.setChildren(childElements);
    }
}
